package cn.antcore.common.config;

import cn.antcore.common.access.OAuth2MethodSecurityExpressionHandler;
import cn.antcore.common.access.OAuth2PermissionEvaluator;
import cn.antcore.common.security.handler.GoAccessDeniedHandler;
import cn.antcore.common.security.handler.GoAuthenticationEntryPoint;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.HttpMethod;
import org.springframework.security.access.expression.method.MethodSecurityExpressionHandler;
import org.springframework.security.authorization.AuthorityAuthorizationManager;
import org.springframework.security.authorization.AuthorizationDecision;
import org.springframework.security.authorization.AuthorizationManager;
import org.springframework.security.config.Customizer;
import org.springframework.security.config.annotation.method.configuration.EnableMethodSecurity;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.core.Authentication;
import org.springframework.security.web.SecurityFilterChain;
import org.springframework.security.web.access.intercept.RequestAuthorizationContext;

import java.util.function.Supplier;

@Configuration
@EnableWebSecurity
@EnableMethodSecurity
public class SecurityConfiguration {

    @Bean
    public SecurityFilterChain filterChain(HttpSecurity http, ObjectMapper objectMapper) throws Exception {
        http.authorizeHttpRequests(auth -> auth.requestMatchers("/file/*").permitAll()
                .requestMatchers(HttpMethod.GET, "/")
                .hasAuthority("SCOPE_all")
                .anyRequest().authenticated()
        );
        http.oauth2ResourceServer(oauth2 -> oauth2.jwt(Customizer.withDefaults()));
        http.exceptionHandling(exception -> exception.accessDeniedHandler(new GoAccessDeniedHandler(objectMapper))
                .authenticationEntryPoint(new GoAuthenticationEntryPoint(objectMapper)));
        return http.build();
    }

    /**
     * 进行OAuth2的权限验证
     */
    @Bean
    public MethodSecurityExpressionHandler expressionHandler() {
        OAuth2MethodSecurityExpressionHandler expressionHandler = new OAuth2MethodSecurityExpressionHandler(new OAuth2PermissionEvaluator());
        expressionHandler.setPermissionEvaluator(new OAuth2PermissionEvaluator());
        return expressionHandler;
    }
}
